#ifndef PUDGE_UI_SPRITE_HPP
#define PUDGE_UI_SPRITE_HPP

namespace pudge { namespace ui {

	/// a simple structure for a simple sprite shader
	
	struct sprite_shader
	{
		typedef pudge::grfx::uniform uniform;
		typedef pudge::grfx::vertex_shader vertex_shader;
		typedef pudge::grfx::frag_shader frag_shader;
		typedef pudge::grfx::shader_program shader_program;

		uniform texture0;
		uniform viewport;

		// shader and program objects are automatically cleaned upon destruction

		vertex_shader vshader;
		frag_shader fshader;
		shader_program program;

		sprite_shader(std::string const& vfile, std::string const& ffile)
			:	vshader(vfile, pudge::grfx::file_tag)
			,	fshader(ffile, pudge::grfx::file_tag)
		{
			// bind position and uv attributes
			pudge::grfx::bind_attribute(program, "position");
			pudge::grfx::bind_attribute(program, "tcoord0");

			// bind shaders to program object
			pudge::grfx::bind_shader(program, vshader);
			pudge::grfx::bind_shader(program, fshader);

			// link program
			pudge::grfx::link_program(program);

			// setup uniforms
			viewport = uniform(program, "viewport");
			pudge::grfx::test_gl_error("");
			texture0 = uniform(program, "tex0");
		}

		template<class Context> void use(Context & c)
		{
			if(c.active_shader() != &program)
			{
				c.active_shader(&program);

				long sampler = 0;
				Context::viewport_type vp = c.viewport();
				pudge::math::vec<2,float> v((float)vp.w, (float)vp.h);

				pudge::grfx::use_program(program);
				pudge::grfx::set_uniform(viewport, v);
				pudge::grfx::set_uniform(texture0, sampler);
			}
		}
	};

	template<class T> struct sprite
	{
		typedef T value_type;

		T		xmin
			,	ymin
			,	xmax
			,	ymax;

		sprite() 
			:	xmin((T)0)
			,	ymin((T)0)
			,	xmax((T)0)
			,	ymax((T)0) {}

		sprite
			(	const T xn
			,	const T yn
			,	const T xx
			,	const T yx )
			:	xmin(xn)
			,	ymin(yn)
			,	xmax(xx)
			,	ymax(yx) {}

		bool operator == (sprite const& s) const
		{
			return	xmin == s.xmin
				&&	xmax == s.xmax
				&&	ymin == s.ymin
				&&	ymax == s.ymax;
		}
	};
}}

#endif